package com.wsz.gateway.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.stereotype.Component;

import javax.crypto.spec.SecretKeySpec;
import java.util.*;

@Component
public class JwtUtils {
    private static final Long JWTREF_TTL = 60 * 60 * 1000L * 24 * 14;//refresh令牌的刷新事件为14day
    private static final Long JWTACS_TTL = 60 * 60 * 1000L * 2;//权限信息token有效时间为2h

    public static final String JWT_KEY = "JSDFSDFSDFASJDHASDASDdfa32dJHASFDA67765asda123";
    public static final String JWT_ACL_KEY = "JSBFSDFSDFASJDHASDASDdfa32dJHASFDA67765asda123";

    public static String createRefreshToken(String username) {
        Long time = System.currentTimeMillis();
        return   JWT.create()
                .withIssuedAt(new Date(time))
                .withExpiresAt(new Date(time + JWTREF_TTL))
                .withIssuer(username)
                .sign(generalKey());
    }

    public static String createAccessToken(String username, String id) {
        Long time = System.currentTimeMillis();
        return   JWT.create()
                .withSubject(id)//主题
                .withIssuedAt(new Date(time))   //生成时间
                .withExpiresAt(new Date(time + JWTACS_TTL))
                .withIssuer(username)   //token发布者
                .sign(generalKey());
    }

    //acl
    public static String createAccessToken(String username, String id,String jwtId) {
        Long time = System.currentTimeMillis();
        return   JWT.create()
                .withSubject(id)//主题
                .withIssuedAt(new Date(time))   //生成时间
                .withExpiresAt(new Date(time + JWTACS_TTL))
                .withIssuer(username)   //token发布者
                //.withAudience(acl)  //观众，相当于接受者
                .withJWTId(jwtId)
                .sign(generalAclKey());
    }

    public static Algorithm generalKey() {
        byte[] encodeKey = Base64.getDecoder().decode(JwtUtils.JWT_KEY);//使用 Base64 编码方案解码输入字节数组/字符串/字节缓冲中的所有字节, 将结果写入新分配的输出字节数组/字节缓冲中.
        String key1 = new SecretKeySpec(encodeKey, 0, encodeKey.length, "HmacSHA256").toString();//将其字节数字组按给定算法加密
        return Algorithm.HMAC256(key1);
    }

    public static Algorithm generalAclKey() {
        byte[] encodeKey = Base64.getDecoder().decode(JwtUtils.JWT_ACL_KEY);//使用 Base64 编码方案解码输入字节数组/字符串/字节缓冲中的所有字节, 将结果写入新分配的输出字节数组/字节缓冲中.
        String key1 = new SecretKeySpec(encodeKey, 0, encodeKey.length, "HmacSHA256").toString();//将其字节数字组按给定算法加密
        return Algorithm.HMAC256(key1);
    }

    public static DecodedJWT parseToken(String jwt) {
        //首先通过调用JWT.require()并传递Algorithm实例来创建 JWTVerifier实例方法build(),
        // 返回的实例是可复用的，因此您可以定义一次，且用它来验证不同的标记。最后调用verifier.verify()来验证token
        return  JWT.require(generalKey()).build().verify(jwt);
    }

    public static DecodedJWT parseAclToken(String jwt) {
        return  JWT.require(generalAclKey()).build().verify(jwt);
    }

}